
#pragma once

#include "rapi.h"
#include "RapiInvokPs.h"
#include "RapiInvokObj.h"
#include "RapiObjS.hxx"

typedef void (*PFNTFCHG)();
class IMemSpace
{
public:
	IMemSpace(PFNTFCHG pfCallBack):m_pfCallBack(pfCallBack){};

public:
	virtual BOOL Read(DWORD dwRdAddr, BYTE* pbBuf, DWORD dwSize)=0;
	virtual BOOL Write(DWORD dwWtAddr, BYTE* pbBuf, DWORD dwSize)=0;

public: 
	virtual BOOL Connect(void* pv){return TRUE;};
	virtual void DisConnect(){};
	virtual BOOL GetCnnctStat(){return TRUE;};

protected:
	void NotifyStatChange()
		{if(NULL!=m_pfCallBack){m_pfCallBack();}};

protected:
	PFNTFCHG m_pfCallBack;
};


class CSmpMemSpace: public IMemSpace
{
public:
	CSmpMemSpace(PFNTFCHG pfCallBack):IMemSpace(pfCallBack) 
		{memset(m_Buf, 0xcd, sizeof(m_Buf));};

public:
	virtual BOOL Read(DWORD dwRdAddr, BYTE* pbBuf, DWORD dwSize);
	virtual BOOL Write(DWORD dwWtAddr, BYTE* pbBuf, DWORD dwSize);

private:
	BYTE m_Buf[4096];
};

/*
BOOL Read(DWORD dwRdAddr, BYTE* pbBuf, DWORD dwSize)
BOOL Write(DWORD dwWtAddr, BYTE* pbBuf, DWORD dwSize)
*/
class CEMemSpace: public IMemSpace
{
public:
	CEMemSpace(PFNTFCHG pfCallBack)
				:IMemSpace(pfCallBack)
				,m_fCnnct(FALSE)
				,m_RAPIObjRdMem(T_IN, T_OUT|T_PTR, T_IN)
				,m_RAPIObjWtMem(T_IN, T_IN|T_PTR, T_IN)
	{};

	~CEMemSpace(){if(FALSE!=m_fCnnct){DisConnect();}};

public:
	virtual BOOL Read(DWORD dwRdAddr, BYTE* pbBuf, DWORD dwSize);
	virtual BOOL Write(DWORD dwWtAddr, BYTE* pbBuf, DWORD dwSize);

public: 
	virtual BOOL Connect(void* pv);	// *pv=dwtimeout
	virtual void DisConnect();
	virtual BOOL GetCnnctStat(){return m_fCnnct;};

private:
	BOOL m_fCnnct;
	IRAPIStream* m_pStream;
	CExpIStrm* m_pExpIStrm;
	CRAPIObjPS* m_pRAPIPS;

	CRetArg3RAPIObj<BOOL, DWORD, BYTE*, DWORD, CISVAL, CISPTR, CISVAL>
				m_RAPIObjRdMem;
	CRetArg3RAPIObj<BOOL, DWORD, BYTE*, DWORD, CISVAL, CISPTR, CISVAL>
				m_RAPIObjWtMem;


	static WCHAR m_wstrDll[];
	static WCHAR m_wstrFun[];
};